#!/usr/bin/python

import sys
import inspect
import re
import argparse
import os

parser = argparse.ArgumentParser(description='Produce and/or checks documentation in googlecode wiki syntax for a python module.')
parser.add_argument('-j', '--job', type=str, choices= ['template', 'check'],
                   help='Job to execute: "template" to generate a template, "check" to check existing wiki file')
parser.add_argument('-m', '--module', type=str,
                   help='Module to check')
args = parser.parse_args()

(module_path, module_name)= os.path.split(args.module)
module_name= module_name.rstrip('.py')

if not module_path in sys.path:
    sys.path.append(module_path)
    
__import__(module_name)

class Function:
    def function_name(self, x):
        return(x)
    def function_args(self, x):  
        return([x])
    def arg_defaults(self, x):
        return([x])
    def arg_types(self, x):
        return([x])
        
mymod= module_name   
all_objs= dir(mymod)
function_list= []
for x in all_objs:
    fun_str= 'mymod.%s' %x
    if inspect.isfunction(eval(fun_str)) is True:
        myfun= eval(fun_str)
        myFun= Function()
        myFun.function_name= x
        myFun.function_args= inspect.getargspec(myfun).args
        if myFun.function_args == []:
            myFun.function_args= ['_No arguments_']
            myFun.arg_types= ['']
        else:
            myFun.arg_types= ['_arg type_'] * len(myFun.function_args)
        myFun.arg_defaults= inspect.getargspec(myfun).defaults
        if myFun.arg_defaults is None:
            myFun.arg_defaults= ['']
        else:
            myFun.arg_defaults= list(myFun.arg_defaults)
        if len(myFun.function_args) > len(myFun.arg_defaults):
            pad= len(myFun.function_args) - len(myFun.arg_defaults)
            myFun.arg_defaults= (['No default'] * pad) + myFun.arg_defaults
        function_list.append(myFun)

if args.job == 'template':
    print('''#summary _A single line summary_\n''')
    print('''<wiki:toc max_depth="3" />\n''')
    print('''= Module description =\n''')
    print('''_What this module does_\n''')
    print('''= Functions =\n''')

    for f in function_list:
        print("== %s ==" %(f.function_name))
        print('_Description of what function %s does_ \n' %f.function_name)
        for arg, default, atype in zip(f.function_args, f.arg_defaults, f.arg_types):
            if arg == ['_No arguments_']:
                print(' * _No arguments_')
            else:
                print(' * *%s*, default= _%s_, type: _type for this arg_' %(arg, default))
                print('_Description of what arg %s does_\n' %(arg))
    print('''= Optional headers =\n''')
    print('''_For example, installation, requirements etc..._\n''')

if args.job == 'check':
    wiki= open(wikifile).readlines()
    i= 0
    f_start= None
    f_end= None
    for line in wiki:
        line= line.strip()
        if re.search('^=\s*Functions\s*=$', line):
            f_start= i
            break
        i += 1
    if f_start is None:
        sys.exit('Could not find the "Functions" section in the docs. Make sure it is formatted as "= Functions ="')
    
    i= 0
    for line in wiki[f_start+1:]:
        line= line.strip()
        if re.search('^={1}[^=]*={1}$', line):
            f_end= f_start + i
            break
        i += 1
    if f_end is None:
        f_end= f_start + i        
    fun_para= wiki[f_start:f_end]
    
    ## Grab all function locations:
    funidx= []
    i= f_start
    for line in wiki[f_start:f_end]:
        if re.search('\s*={2}[^=]*={2}\s*', line):
            funidx.append(i)
        i += 1
    funheaders= [wiki[x] for x in funidx]
    funnames= []
    for x in funheaders:
        x= x.strip()
        x= x.strip('==')
        x= x.strip()
        funnames.append(x)
    ## Check 1) Functions are documented only once:
    xd= {}
    for n in funnames:   
        xd[n] = xd.get(n, 0) + 1 ## Increament value of n by 1
    for k in xd.keys():
        if xd[k] > 1:
            print('Warning: function %s is documented %s times' %(k, xd[k]))
    
    ## Check 2) Are the functions in wiki in one-to-one relation with thos in the module?
    mod_funs= [x.function_name for x in function_list]
    not_documented= [x for x in mod_funs if x not in funnames]
    not_in_module= [x for x in funnames if x not in mod_funs]
    if not not_documented == []:
        for x in not_documented:
            print('Warning: function %s is not documented.' %x)
    if not not_in_module == []:
        for x in not_in_module:
            print('Warning: function %s is not present in module.' %x)
    
    ## Check each function
    f_ends= funidx[1:] + [f_end]
    print(funidx)
    print(f_ends)
sys.exit()